package com.uzai.console.service.alipaymch.impl;

import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AppTokenExchangeSubElement;
import com.alipay.api.request.AlipayOpenAuthTokenAppRequest;
import com.alipay.api.request.AlipayOpenInviteOrderCreateRequest;
import com.alipay.api.response.AlipayOpenAuthTokenAppResponse;
import com.alipay.api.response.AlipayOpenInviteOrderCreateResponse;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.taobao.api.internal.toplink.embedded.websocket.util.StringUtil;
import com.uzai.common.enums.RedisCacheKeyEnum;
import com.uzai.common.exception.BusinessException;
import com.uzai.common.result.ResponseCode;
import com.uzai.common.utils.DateUtil;
import com.uzai.console.common.utils.Tools;
import com.uzai.console.config.UzaiConsoleSysConfig;
import com.uzai.console.constant.CacheKey;
import com.uzai.console.dto.alipaydetail.AlipayDetailAlipayUrlDao;
import com.uzai.console.dto.alipaymch.AlipayMchAppAuthSignUrlDao;
import com.uzai.console.dto.alipaymch.AlipayMchAuthDto;
import com.uzai.console.dto.alipaymch.AlipayMchAuthIdDto;
import com.uzai.console.dto.alipaymch.AlipayMchAuthQuery;
import com.uzai.console.dto.uzaichat.kefuuser.KefuUserQuery;
import com.uzai.console.entity.AlipayDetail;
import com.uzai.console.entity.AlipayMchAuth;
import com.uzai.console.entity.KefuUser;
import com.uzai.console.mapper.AlipayMchAuthMapper;
import com.uzai.console.service.alipaymch.AlipayMchAppAuthService;
import com.uzai.console.vo.alipaydetail.AlipayDetailCreateVo;
import com.uzai.console.vo.alipaymch.AlipayMchAppAuthSignUrlVo;
import com.uzai.console.vo.alipaymch.AlipayMchAuthVo;
import com.uzai.console.vo.base.SelectKeyVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Auther: lucher
 * @Date: 2021/12/14 16:46
 * @Description:
 */
@Service
public class AlipayMchAppAuthServiceImpl implements AlipayMchAppAuthService {

    private static Logger logger = LoggerFactory.getLogger(AlipayMchAppAuthServiceImpl.class);

    @Autowired
    private AlipayMchAuthMapper alipayMchAuthMapper;
    @Autowired
    private UzaiConsoleSysConfig uzaiConsoleSysConfig;
    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 生成商户签约页面
     * @author liuqi
     * @date 2021/8/13 11:38
     * @return null
     */
    public AlipayMchAppAuthSignUrlVo mchInviteSignUrl(){
        AlipayMchAppAuthSignUrlVo alipayMchAppAuthSignUrlVo = new AlipayMchAppAuthSignUrlVo();
        try {

            AlipayClient alipayClient = new DefaultAlipayClient(uzaiConsoleSysConfig.getAlipayGateway(),
                    uzaiConsoleSysConfig.getAlipayPartnerAppId(), uzaiConsoleSysConfig.getAlipayPartnerAppPrivateKey(),
                    uzaiConsoleSysConfig.getAlipayFormat(), uzaiConsoleSysConfig.getAlipayCharset(),
                    uzaiConsoleSysConfig.getAlipayPartnerPublicKey(), uzaiConsoleSysConfig.getAlipaySignType());

            AlipayOpenInviteOrderCreateRequest request = new AlipayOpenInviteOrderCreateRequest();

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("isv_biz_id", IdWorker.getIdStr());
            jsonObject.put("isv_return_url",uzaiConsoleSysConfig.getAlipayMchauthReturnurl());
            request.setBizContent(JSONObject.toJSONString(jsonObject));

            AlipayOpenInviteOrderCreateResponse response = alipayClient.pageExecute(request);
            if(response != null){
                //获取需提交的form表单
                String submitFormData = response.getBody();
                //保存到缓存当中
                String id = IdWorker.getIdStr();
                String redis_key = String.format(CacheKey.ALIPAY_MCH_APP_SIGNURL, id);
                redisTemplate.opsForValue().set(redis_key, submitFormData,5, TimeUnit.MINUTES);
                //返回支付页面
                alipayMchAppAuthSignUrlVo.setUrl(uzaiConsoleSysConfig.getAlipayMchinvitesignUrl()+"?id=" + id);
            }
        } catch (AlipayApiException e) {
        }
        return alipayMchAppAuthSignUrlVo;
    }

    /**
     * 查询商户签约页面url
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param alipayMchAppAuthSignUrlDao
     * @return null
     */
    public AlipayMchAppAuthSignUrlVo findAlipayMchAppAuthSignUrl(AlipayMchAppAuthSignUrlDao alipayMchAppAuthSignUrlDao){

        AlipayMchAppAuthSignUrlVo alipayMchAppAuthSignUrlVo = new AlipayMchAppAuthSignUrlVo();

        if(alipayMchAppAuthSignUrlDao.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id");
        }
        //从缓存当中获取
        String redis_key = String.format(CacheKey.ALIPAY_MCH_APP_SIGNURL, alipayMchAppAuthSignUrlDao.getId());
        Object object = redisTemplate.opsForValue().get(redis_key);
        if(object != null){
            alipayMchAppAuthSignUrlVo.setUrl(object.toString());
        }
        return alipayMchAppAuthSignUrlVo;
    }

    @Override
    public void mchAppAuthToken(String app_id, String app_auth_code, String state) {
        try {
            // 获取授权
            AlipayClient alipayClient = new DefaultAlipayClient(uzaiConsoleSysConfig.getAlipayGateway() ,
                    uzaiConsoleSysConfig.getAlipayPartnerAppId() , uzaiConsoleSysConfig.getAlipayPartnerAppPrivateKey() , uzaiConsoleSysConfig.getAlipayFormat() ,  uzaiConsoleSysConfig.getAlipayCharset()
                    ,  uzaiConsoleSysConfig.getAlipayPartnerPublicKey() , uzaiConsoleSysConfig.getAlipaySignType());
            AlipayOpenAuthTokenAppRequest request = new AlipayOpenAuthTokenAppRequest();
            Map<String,String> param = new HashMap<>();
            param.put("grant_type","authorization_code");
            param.put("code",app_auth_code);
            request.setBizContent(JSONObject.toJSONString(param));
            AlipayOpenAuthTokenAppResponse response = alipayClient.execute(request);
            logger.info("get auth token result:{}",response.getBody());
            if (response.getTokens()!=null && response.getTokens().size()>0){
                AppTokenExchangeSubElement element = response.getTokens().get(0);
                int now = DateUtil.getTime();
                AlipayMchAuth alipayMchAuth = new AlipayMchAuth();
                alipayMchAuth.setId(IdWorker.getId());
                alipayMchAuth.setPartnerAppId(app_id);
                alipayMchAuth.setAppAuthToken(element.getAppAuthToken());
                alipayMchAuth.setAppRefreshToken(element.getAppRefreshToken());
                alipayMchAuth.setAuthAppId(element.getAuthAppId());
                alipayMchAuth.setAuthTime(now);
                alipayMchAuth.setExpiresIn(Integer.parseInt(element.getExpiresIn()));
                alipayMchAuth.setReExpiresIn(Integer.parseInt(element.getReExpiresIn()));
                alipayMchAuth.setUserId(element.getUserId());
                alipayMchAuth.setMerId(Long.parseLong(state));
                alipayMchAuth.setDef(0); //不默认
                alipayMchAuth.setRemark(null);
                alipayMchAuth.setCreateTime(now);
                alipayMchAuth.setUpdateTime(now);

                AlipayMchAuth oldAlipayMchAuth = alipayMchAuthMapper.get(app_id, alipayMchAuth.getAuthAppId(), alipayMchAuth.getUserId(), alipayMchAuth.getMerId());
                if (oldAlipayMchAuth == null){
                    alipayMchAuthMapper.insert(alipayMchAuth);
                }

                //修改该支付宝账户的授权
                alipayMchAuthMapper.updateByUserAndPartnerAppIdAndAuthAppId(alipayMchAuth);

            }else {
                throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION,"授权失败");
            }
        } catch (AlipayApiException e) {
            logger.error("err:",e);
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION,e.getMessage());
        }catch (BusinessException e) {
            logger.error("err:",e);
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION,e.getMessage());
        }
    }

    /**
     * 查询支付宝授权列表
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param alipayMchAuthQuery
     * @return null
     */
    public Page<AlipayMchAuthVo> findAlipayMchAuthList(AlipayMchAuthQuery alipayMchAuthQuery){
        //新建返回到页面的LIST对象
        List<AlipayMchAuthVo> alipayMchAuthPageVoList = new ArrayList<>();

        //执行分页查询对象
        Page<AlipayMchAuth> page = new Page<>();
        alipayMchAuthQuery.convert(page);
        ArrayList<AlipayMchAuth> alipayMchAuthList =  alipayMchAuthMapper.findByList(page, alipayMchAuthQuery);
        if(alipayMchAuthList != null && alipayMchAuthList.size() > 0){
            for (AlipayMchAuth alipayMchAuth : alipayMchAuthList){
                AlipayMchAuthVo alipayMchAuthVo = new AlipayMchAuthVo();
                BeanUtils.copyProperties(alipayMchAuth, alipayMchAuthVo);
                //到期时间
                alipayMchAuthVo.setExpireTime(Tools.getInteger(alipayMchAuthVo.getAuthTime()).intValue() + alipayMchAuthVo.getExpiresIn());
                alipayMchAuthPageVoList.add(alipayMchAuthVo);
            }
        }

        //返回到页面分页对象
        Page<AlipayMchAuthVo> pageVo = new Page<>();
        BeanUtils.copyProperties(page, pageVo);
        pageVo.setRecords(alipayMchAuthPageVoList);
        //将分页信息复制到返回到页面的分页MO当中
        return pageVo;
    }

    /**
     * 修改支付宝授权备注
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param alipayMchAuthDto
     * @return null
     */
    public void updateRemark(AlipayMchAuthDto alipayMchAuthDto){
        if(alipayMchAuthDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "id不能为空");
        }

        AlipayMchAuth alipayMchAuth = alipayMchAuthMapper.selectById(alipayMchAuthDto.getId(), alipayMchAuthDto.getMerId());
        if(alipayMchAuth == null ){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该支付宝授权不存在");
        }

        alipayMchAuth.setRemark(Tools.getStr(alipayMchAuthDto.getRemark()));
        int now = DateUtil.getTime();
        alipayMchAuth.setUpdateTime(now);
        alipayMchAuthMapper.updateRemarkAndTransferinfoById(alipayMchAuth);
    }

    /**
     * 修改支付宝授权备注
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param alipayMchAuthDto
     * @return null
     */
    public void updateTransferinfo(AlipayMchAuthDto alipayMchAuthDto){
        if(alipayMchAuthDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "id不能为空");
        }

        AlipayMchAuth alipayMchAuth = alipayMchAuthMapper.selectById(alipayMchAuthDto.getId(), alipayMchAuthDto.getMerId());
        if(alipayMchAuth == null ){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该支付宝授权不存在");
        }

        alipayMchAuth.setTransferinfo(Tools.getStr(alipayMchAuthDto.getTransferinfo()));
        int now = DateUtil.getTime();
        alipayMchAuth.setUpdateTime(now);
        alipayMchAuthMapper.updateRemarkAndTransferinfoById(alipayMchAuth);
    }

    /**
     * 修改支付宝授权
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param alipayMchAuthIdDto
     * @return null
     */
    public void deleteAlipayMchAuth(AlipayMchAuthIdDto alipayMchAuthIdDto){
        if(alipayMchAuthIdDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "id不能为空");
        }

        AlipayMchAuth alipayMchAuth = alipayMchAuthMapper.selectById(alipayMchAuthIdDto.getId(), alipayMchAuthIdDto.getMerId());
        if(alipayMchAuth == null ){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该支付宝授权不存在");
        }

        //删除
        alipayMchAuthMapper.deleteById(alipayMchAuthIdDto.getId(), alipayMchAuthIdDto.getMerId());
    }

    /**
     * 查询支付宝授权列表
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param
     * @return null
     */
    public List<SelectKeyVo> findAlipayMchAuthListSelect(AlipayMchAuthQuery alipayMchAuthQuery){
        //新建返回到页面的LIST对象
        List<SelectKeyVo> selectKeyVoList = new ArrayList<>();

        //执行分页查询对象
        ArrayList<AlipayMchAuth> alipayMchAuthList =  alipayMchAuthMapper.findByList(alipayMchAuthQuery);
        if(alipayMchAuthList != null && alipayMchAuthList.size() > 0){
            for (AlipayMchAuth alipayMchAuth : alipayMchAuthList){
                SelectKeyVo selectKeyVo = new SelectKeyVo();
                selectKeyVo.setKey(String.valueOf(alipayMchAuth.getId()));
                String value = Tools.getStr(alipayMchAuth.getUserId());
                String remark = alipayMchAuth.getRemark();
                if(StringUtils.isNotBlank(remark)){
                    value = value + "(" + remark + ")";
                }
                selectKeyVo.setValue(value);
                selectKeyVo.setTransferinfo(alipayMchAuth.getTransferinfo());
                selectKeyVoList.add(selectKeyVo);
            }
        }

        return selectKeyVoList;
    }

}
